import json
import os
import jwt
import datetime
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
import requests
import random
import string

from .pipeline import fetch_pipeline_url

RANDOM_LEN = 6

### Atomgit
create_automated_checks_url = "https://api.atomgit.com/repos/%s/%s/check-runs"
update_automated_checks_url = "https://api.atomgit.com/repos/%s/%s/check-runs/%s"

# 从PEM文件中读取私钥的函数
def get_private_key_from_pem(pem_file_path):
    with open(pem_file_path, 'rb') as key_file:
        private_key = serialization.load_pem_private_key(
            key_file.read(),
            password=None,
            backend=default_backend()
        )
    return private_key

def get_application_by_app_id(applications, app_id):
    for app in applications:
        if int(app.get('app_id'))==int(app_id):
            return app
    return None

def get_ats_token(app_id, pem_file_path):
    private_key = get_private_key_from_pem(pem_file_path)
    current_time = datetime.datetime.utcnow()
    encoded_jwt = jwt.encode(
        {
            "iss": app_id,  # 签发人
            "iat": current_time - datetime.timedelta(minutes=1),  # 签发时间（当前时间减去1分钟）
            "exp": current_time + datetime.timedelta(minutes=60),  # 过期时间（当前时间加上60分钟）
        },
        private_key,  # 用于签名的RSA私钥
        algorithm="RS256"
    )
    headers = {
        "Authorization": "Bearer " + encoded_jwt
    }
    applications = requests.request(
        method='GET',
        url="https://api.atomgit.com/app/installations", 
        headers = headers
    )
    app = get_application_by_app_id(
        applications=applications.json(), 
        app_id=app_id
    )
    if app is None:
        print(f'找不到APP ID为{app_id}的应用')
        return None
    # 发送POST请求, 获取ats_token
    ats_token = requests.request(
        method='POST',
        url=app.get('access_tokens_url'),
        headers=headers
    )
    # 检查响应是否成功
    if ats_token.status_code == 201:
        return ats_token.json().get('token')
    else:
        print("请求失败，状态码:", ats_token.status_code)
        print("响应内容:", ats_token.text)

def convert_unix_timestamp(unix_timestamp):
    # 将 Unix 时间戳转换为 datetime 对象
    dt_object = datetime.datetime.utcfromtimestamp(unix_timestamp / 1000)  # 注意除以1000以转换为秒
    # 将 datetime 对象转换为指定格式的字符串
    formatted_date_time = dt_object.strftime('%Y-%m-%dT%H:%M:%SZ')
    return formatted_date_time

class Atomgit(object):
    def __init__(self, config, payload, pipeline_detail):
        self.config = config
        self.payload = payload
        self.pipeline = pipeline_detail
        self.ats_token = get_ats_token(config.atomgit_app_id, config.atomgit_app_pem_file_path)
        print("ats token: ", self.ats_token)
    
    def create(self):
        pipeline_link = fetch_pipeline_url(self.config.huawei_cloud_endpoint, self.pipeline['project_id'], self.pipeline['pipeline_id'], self.pipeline['id'])
        data = json.dumps({
            "name": "%s@%s" % (self.pipeline['name'], self.payload['pull_request', 'head', 'sha']),
            "head_sha": self.payload['pull_request', 'head', 'sha'],
            "status": "in_progress",
            "started_at": convert_unix_timestamp(self.pipeline['start_time']),
            "conclusion": "",
            "completed_at": "",
            "action": {
                "label": "",
                "description": "",
                "identifier": ""
            },
            "output": {
                "title": "CodeArts 流水线",
                "summary": "Pipeline: \n <%s>" + pipeline_link,
                "text": "",
                "annotations": {
                },
                "images": {
                    "alt": "",
                    "image_url": "",
                    "caption": ""
                }
            }
            })
        headers={
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.ats_token
        }
        (org, repo) = self.payload['repository', 'full_name'].split('/')
        resp = requests.request(
            method='POST',
            url=create_automated_checks_url % (org, repo),
            headers=headers,
            data=data
        )
        if resp.status_code != 201:
            print('创建Atomgit自动化检查失败')
            print(resp.text)
            raise requests.exceptions.RequestException()
        return resp
    
    def update(self, check_run_id):
        pipeline_link = fetch_pipeline_url(self.config.huawei_cloud_endpoint, self.pipeline['project_id'], self.pipeline['pipeline_id'], self.pipeline['id'])
        data = json.dumps({
            "name": "%s@%s" % (self.pipeline['name'], self.payload['pull_request', 'head', 'sha']),
            "head_sha": self.payload['pull_request', 'head', 'sha'],
            "status": "completed",
            "started_at": convert_unix_timestamp(self.pipeline['start_time']),
            "conclusion": show_conclusion(self.pipeline['status']),
            "completed_at": convert_unix_timestamp(self.pipeline['end_time']),
            "action": {
                "label": "",
                "description": "",
                "identifier": ""
            },
            "output": {
                "title": "CodeArts 流水线",
                "summary": "Pipeline: \n <%s>" % pipeline_link,
                "text": "",
                "annotations": {
                },
                "images": {
                    "alt": "",
                    "image_url": "",
                    "caption": ""
                }
            }
            })
        headers={
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.ats_token
        }
        (org, repo) = self.payload['repository', 'full_name'].split('/')
        resp = requests.request(
            method='PATCH',
            url=update_automated_checks_url % (org, repo, check_run_id),
            headers=headers,
            data=data
        )
        if resp.status_code != 201:
            print('更新Atomgit自动化检查失败')
            print(resp.text)
            raise requests.exceptions.RequestException()
        return resp
   
def show_conclusion(pipeline_status):
    if pipeline_status == "CANCELED":
        return "cancelled"
    if pipeline_status == "FAILED":
        return "failure"
    if pipeline_status == "COMPLETED":
        return "success"
    
def generate_random_string(length):
    # 选择所有的小写字母和大写字母
    letters = string.ascii_letters
    # 生成指定长度的随机字符串
    random_string = ''.join(random.choice(letters) for i in range(length))
    return random_string